//
// security_helper.cpp
// libprotea
// Tools Library for the Protea Project / User and Group security helper functions
// Copyright (C) 2003, 2004, 2005 eXegeSys, Inc.
// Copyright (C) 2008 Bruce A. James
//
// This program is part of the Protea Project.
//
// The Protea Project is free software; you can redistribute it and/or modify it 
// under the terms of the GNU General Public License as published by the 
// Free Software Foundation, either version 3 of the License, or (at your 
// option) any later version.
//
// The Protea Project is distributed in the hope that it will be useful, but 
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
// for more details.
// 
// You should have received a copy of the GNU General Public License along 
// with this program.  If not, see <http://www.gnu.org/licenses/>.
// 
// Please send correspondence to:
// 
// theproteaproject@gmail.com
//

#include "../defines.h"
#include "security.h"
#include "security_helper.h"
#include "message.h"
#include "AppInterface.h"

security_info_manager::security_info_manager() {
	user_name = NULL;
	user_password = NULL;
	group_name = NULL;
	description = NULL;
};



void security_info_manager::FromMessageType( security_update_message* input ) {
	char* offset = input->data;
	FillSecurityVariable( user_name, input->user_name_len, offset );
	FillSecurityVariable( user_password, input->user_pass_len, offset );
	FillSecurityVariable( group_name, input->group_name_len, offset );
	FillSecurityVariable( description, input->descr_len, offset );
};



void security_info_manager::FillSecurityVariable( char*& result, int len, char*& offset ) {
	if (len) {
		result = new char[ len + 1 ];
		memcpy( result, offset, len );
		result[len]=0;
		offset += len;
	};
};



void security_info_manager::FillMessageVariable( char* result, int len, char*& offset ) {
	memcpy( offset, result, len );
	offset += len;
};



void security_info_manager::SubmitChange( security_update_mode mode, XCAppInterface* app ) {
	// Determine the required message size
	security_update_message info;
	memset( &info, 0, sizeof( security_update_message ) );

	info.mode = mode;
	if (user_name)
		info.user_name_len = strlen( user_name );
	if (user_password)
		info.user_pass_len = strlen( user_password );
	if (group_name)
		info.group_name_len = strlen( group_name );
	if (description)
		info.descr_len = strlen( description );

	int size = info.user_name_len + info.user_pass_len + info.group_name_len + info.descr_len;

	// Create the dispatch message
	XCToolsMessage msg_send( app );
	disp_message* disp_info;
	msg_send.CreateMsg( DISP_MESSAGE_SIZE + sizeof( security_update_message ) + size );
	msg_send.SetHeader( msg_dispatch, src_gcs, dest_all, true, false );
	disp_info = (disp_message*)msg_send.GetDataPtr();
	disp_info->opcode = disp_security_change;

	// Fill in the security information now
	security_update_message* update = (security_update_message*)&disp_info->data;
	memcpy( update, &info, sizeof( security_update_message ) );

	char* offset = update->data;
	FillMessageVariable( user_name, update->user_name_len, offset );
	FillMessageVariable( user_password, update->user_pass_len, offset );
	FillMessageVariable( group_name, update->group_name_len, offset );
	FillMessageVariable( description, update->descr_len, offset );

	// GCS should also respond to this one
	app->HandleSecurityChange( &msg_send );

	// Send this message out to everyone
	app->BroadcastMessage( msg_src, &msg_send );
};
